## Adapter 
### ary
Creates a function that accepts up to n arguments, ignoring any additional arguments.
```javascript
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
```

example
```javascript
const firstTwoMax = ary(Math.max, 2);
[[2, 6, 'a'], [8, 4, 6], [10]].map(x => firstTwoMax(...x)); // [6, 8, 10]
```

### call
Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

```javascript
const call = (key, ...args) => context => context[key](...args);
```

example
```javascript
Promise.resolve([1, 2, 3])
  .then(call('map', x => 2 * x))
  .then(console.log); //[ 2, 4, 6 ]
const map = call.bind(null, 'map');
Promise.resolve([1, 2, 3])
  .then(map(x => 2 * x))
  .then(console.log); //[ 2, 4, 6 ]
```

### collectInto
Changes a function that accepts an array into a variadic function.

```javascript
const collectInto = fn => (...args) => fn(args);
```

example
```javascript
const Pall = collectInto(Promise.all.bind(Promise));
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3));
Pall(p1, p2, p3).then(console.log); // [1, 2, 3] (after about 2 seconds)
```

### filp
Flip takes a function as an argument, then makes the first argument the last.

```javascript
const flip = fn => (first, ...rest) => fn(...rest, first);
```

example
```javascript
let a = { name: 'John Smith' };
let b = {};
const mergeFrom = flip(Object.assign);
let mergePerson = mergeFrom.bind(null, a);
mergePerson(b); // == b
b = {};
Object.assign(b, a); // == b
```

### over
Creates a function that invokes each provided function with the arguments it receives and returns the results.

```javascript
const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
```

example
```javascript
const minMax = over(Math.min, Math.max);
minMax(1, 2, 3, 4, 5); // [1,5]
```

### overArgs
Creates a function that invokes the provided function with its arguments transformed.

```javascript
const overArgs = (fn, transforms) => (...args) => fn(...args.map((val, i) => transforms[i](val)));
```

example
```javascript
const square = n => n * n;
const double = n => n * 2;
const fn = overArgs((x, y) => [x, y], [square, double]);
fn(9, 3); // [81, 6]
```

### pipeAsyncFunctions
Performs left-to-right function composition for asynchronous functions.

```javascript
const pipeAsyncFunctions = (...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));
```

example
```javascript
const sum = pipeAsyncFunctions(
  x => x + 1,
  x => new Promise(resolve => setTimeout(() => resolve(x + 2), 1000)),
  x => x + 3,
  async x => (await x) + 4
);
(async () => {
  console.log(await sum(5)); // 15 (after one second)
})();
```

### promisify
Converts an asynchronous function to return a promise.

```javascript
const promisify = func => (...args) =>
  new Promise((resolve, reject) =>
    func(...args, (err, result) => (err ? reject(err) : resolve(result)))
  );
```

example
```javascript
const delay = promisify((d, cb) => setTimeout(cb, d));
delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s
```

### rearg
Creates a function that invokes the provided function with its arguments arranged according to the specified indexes.

```javascript
const rearg = (fn, indexes) => (...args) =>
  fn(
    ...args.reduce(
      (acc, val, i) => ((acc[indexes.indexOf(i)] = val), acc),
      Array.from({ length: indexes.length })
    )
  );
```

example
```javascript
var rearged = rearg(
  function(a, b, c) {
    return [a, b, c];
  },
  [2, 0, 1]
);
rearged('b', 'c', 'a'); // ['a', 'b', 'c']
```